package com.ultrapower.commons.utils;

import org.apache.http.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;


public class HttpHelper {
	private static int SocketTimeout = 13000;// 5秒
	private static int ConnectTimeout = 13000;// 5秒

	public  final  static String SIGN="signature";
	public  final  static String TIME="time";

	public  final  static String DATA="data";
	public  final  static String RN ="rn";
	public  final  static String USER ="user";





	public static String getUrl(String key,String user)throws Exception{
		String time=String.valueOf(new Date().getTime());
		String random= getRandom();
		String sign= getSignAndMD5(key,time,random);
//		System.out.println(time);
//		System.out.println(random);
//		System.out.println(sign);
		return "time="+time+"&rn="+random+"&signature="+sign+"&user="+user;
	}

	public static String strToMd5(String str, String charSet) throws Exception {
		String md5Str = null;
		if (str != null && str.length() != 0) {
			try {
				MessageDigest md = MessageDigest.getInstance("MD5");
				md.update(str.getBytes(charSet));
				byte b[] = md.digest();
				int i;
				StringBuffer buf = new StringBuffer("");
				for (int offset = 0; offset < b.length; offset++) {
					i = b[offset];
					if (i < 0)
						i += 256;
					if (i < 16)
						buf.append("0");
					buf.append(Integer.toHexString(i));
				}
				md5Str = buf.toString();
			} catch (NoSuchAlgorithmException e) {
				throw new Exception("MD5加密发生异常。加密串：" + str);
			} catch (UnsupportedEncodingException e2) {
				throw new Exception("MD5加密发生异常。加密串：" + str);
			}
		}
		return md5Str;
	}

	/**
	 * 按照字典序逆序拼接参数
	 *
	 * @param params
	 * @return
	 */
	public static String getSign(String... params) {
		List<String> srcList = new ArrayList<String>();
		for (String param : params) {
			srcList.add(param);
		}
		// 按照字典序逆序拼接参数
		Arrays.sort(params);
		Collections.sort(srcList, String.CASE_INSENSITIVE_ORDER);
		Collections.reverse(srcList);
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < srcList.size(); i++) {
			sb.append(srcList.get(i));
		}
		return sb.toString();
	}

	/***
	 * MD5加密调用
	 */
	public static String getSignAndMD5(String... params) throws Exception{
		String sign = getSign(params);
		return strToMd5(sign, "utf-8");
	}

	public static String getRandom(){
		Random r = new Random();
		long num = Math.abs(r.nextLong() % 10000000000L);
		String s = String.valueOf(num);
		for(int i = 0; i < 10-s.length(); i++){
			s = "0" + s;
		}
		return s;
	}

	public static String post(String user,String key,String url, Object params) throws Exception {
		url=url+"?"+getUrl(key,user);
		String result = "";
		HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
		CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
		RequestConfig requestConfig = RequestConfig.custom()
				.setSocketTimeout(SocketTimeout)
				.setConnectTimeout(ConnectTimeout).build();
		HttpPost httpPost = new HttpPost(url);
		StringEntity stringEntity = new StringEntity(JsonHelper.getInstance()
				.write(params),"utf-8");

		httpPost.setEntity(stringEntity);
		httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");
		httpPost.setConfig(requestConfig);

		HttpResponse httpResponse = closeableHttpClient.execute(httpPost);
		StatusLine statusLine = httpResponse.getStatusLine();
		int statusCode = statusLine.getStatusCode();

		if (statusCode == HttpStatus.SC_OK
				|| statusCode == HttpStatus.SC_PARTIAL_CONTENT) {
			HttpEntity entity = httpResponse.getEntity();
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
				EntityUtils.consume(entity);
			}
			closeableHttpClient.close();
		} else {
			throw new Exception("bad request:statusCode=" + statusCode);
		}

		return result;
	}



	private static List<NameValuePair> buildParam(Map<String, String> params) {
		// 添加参数
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		if (params != null && params.keySet().size() > 0) {
			Iterator<Map.Entry<String, String>> iterator = params.entrySet()
					.iterator();
			while (iterator.hasNext()) {
				Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator
						.next();
				nvps.add(new BasicNameValuePair((String) entry.getKey(),
						(String) entry.getValue()));
			}
		}
		return nvps;
	}
}
